import {
  Request,
  Response,
  Router,
} from 'express';
import * as XLSX from 'xlsx';

import { EnumStatusCode } from '@shared/constant/enum';

import {
  Exam,
  ExamRecord,
} from '../models/exam.model';

/**
 * @tittle 考试记录路由
 * @description 该路由处理考试记录的相关操作，包括获取考试记录列表、获取单个考试记录详情、创建考试记录等
 */
export const examRecordRouter = Router();

// 获取考试记录列表（支持分页和筛选）
examRecordRouter.get("/list", async (req: Request, res: Response) => {
  console.log("exam record list req", req.user);

  try {
    const { 
      page = 1, 
      limit = 20, 
      exam_id, 
      status, 
      username,
      start_date,
      end_date
    } = req.query;

    const user = req.user;

    // 如果没有登录用户，则返回未授权错误
    if (!user?.user_id && user?.role !== "admin") {
      return res.status(EnumStatusCode.UNAUTHORIZED).json({
        code: EnumStatusCode.UNAUTHORIZED,
        message: "未授权访问",
        data: null,
      });
    }

    const filter: any = {};

    // 如果是普通用户，只能查看自己的记录
    if (user.role !== "admin" && user.user_id) {
      filter.user_id = user.user_id;
    }

    // 管理员可以根据条件筛选
    if (user.role === "admin") {
      if (exam_id) filter.exam_id = exam_id;
      if (status) filter.status = status;
      
      // 根据用户名筛选（需要先查用户）
      if (username) {
        const { User } = await import('../models/user.model');
        const users = await User.find({ 
          username: { $regex: username, $options: 'i' } 
        }).select('_id');
        
        if (users.length > 0) {
          filter.user_id = { $in: users.map(u => u._id) };
        } else {
          // 如果没有匹配的用户，返回空结果
          return res.json({
            code: EnumStatusCode.SUCCESS,
            message: "success",
            data: {
              data: [],
              total_records: 0,
              page: parseInt(page as string),
              limit: parseInt(limit as string),
              total_page: 0,
            },
          });
        }
      }

      // 时间范围筛选
      if (start_date || end_date) {
        filter.start_time = {};
        if (start_date) {
          filter.start_time.$gte = new Date(start_date as string);
        }
        if (end_date) {
          const endDate = new Date(end_date as string);
          endDate.setHours(23, 59, 59, 999); // 设置为当天的最后一刻
          filter.start_time.$lte = endDate;
        }
      }
    } else {
      // 普通用户的筛选条件
      if (exam_id) filter.exam_id = exam_id;
      if (status) filter.status = status;
    }

    const limitNum = parseInt(limit as string);
    const skip = (parseInt(page as string) - 1) * limitNum;

    const records = await ExamRecord.find(filter)
      .populate("user_id", "username phone")
      .populate("exam_id", "exam_name")
      .skip(skip)
      .limit(limitNum)
      .sort({ start_time: -1 });

    const total = await ExamRecord.countDocuments(filter);

    res.json({
      code: EnumStatusCode.SUCCESS,
      message: "success",
      data: {
        data: records,
        total_records: total,
        page: parseInt(page as string),
        limit: limitNum,
        total_page: Math.ceil(total / limitNum),
      },
    });
  } catch (error) {
    console.error("获取考试记录列表失败:", error);
    res.status(EnumStatusCode.INTERNAL_SERVER_ERROR).json({
      code: EnumStatusCode.INTERNAL_SERVER_ERROR,
      message: "服务器内部错误",
      data: null,
    });
  }
});

// 导出考试记录到Excel
examRecordRouter.get('/export', async (req: Request, res: Response) => {
  try {
    const {
      exam_id,
      user_name,
      real_name,
      start_time,
      end_time,
      status,
      min_score,
      max_score,
    } = req.query;

    // 构建查询条件
    const query: any = {};
    
    if (exam_id) {
      query.exam_id = exam_id;
    }
    
    if (status && status !== 'all') {
      query.status = status;
    }
    
    if (min_score !== undefined && min_score !== '') {
      query.user_score = { ...query.user_score, $gte: Number(min_score) };
    }
    
    if (max_score !== undefined && max_score !== '') {
      query.user_score = { ...query.user_score, $lte: Number(max_score) };
    }
    
    if (start_time) {
      query.start_time = { ...query.start_time, $gte: new Date(start_time as string) };
    }
    
    if (end_time) {
      query.start_time = { ...query.start_time, $lte: new Date(end_time as string) };
    }

    // 查询考试记录并填充用户和考试信息
    const examRecords = await ExamRecord.find(query)
      .populate('user_id', 'username phone')
      .populate('exam_id', 'exam_name')
      .sort({ start_time: -1 });

    // 过滤用户名或真实姓名
    let filteredRecords = examRecords;
    if (user_name) {
      filteredRecords = examRecords.filter(record => {
        const user = record.user_id as any;
        return user?.username?.includes(user_name as string);
      });
    }
    
    if (real_name) {
      filteredRecords = filteredRecords.filter(record => {
        const user = record.user_id as any;
        return user?.username?.includes(real_name as string);
      });
    }

    // 准备Excel数据
    const excelData = filteredRecords.map(record => {
      const user = record.user_id as any;
      const exam = record.exam_id as any;
      
      // 计算用时（如果有提交时间）
      let durationMinutes = '';
      if (record.submit_time && record.start_time) {
        const duration = (new Date(record.submit_time).getTime() - new Date(record.start_time).getTime()) / (1000 * 60);
        durationMinutes = Math.round(duration).toString();
      }
      
      return {
        '考试名称': exam?.exam_name || '',
        '用户名': user?.username || '',
        '手机号': user?.phone || '',
        '开始时间': record.start_time ? new Date(record.start_time).toLocaleString('zh-CN') : '',
        '结束时间': record.submit_time ? new Date(record.submit_time).toLocaleString('zh-CN') : '',
        '用时(分钟)': durationMinutes,
        '得分': record.user_score || 0,
        '总分': record.total_score || 0,
        '状态': record.status === 'completed' ? '已完成' : 
                record.status === 'in_progress' ? '进行中' : 
                record.status === 'timeout' ? '超时' : '未知',
        '是否超时': record.is_timeout ? '是' : '否',
      };
    });

    // 创建工作簿和工作表
    const workbook = XLSX.utils.book_new();
    const worksheet = XLSX.utils.json_to_sheet(excelData);

    // 设置列宽
    const columnWidths = [
      { wch: 20 }, // 考试名称
      { wch: 15 }, // 用户名
      { wch: 15 }, // 手机号
      { wch: 20 }, // 开始时间
      { wch: 20 }, // 结束时间
      { wch: 12 }, // 用时
      { wch: 10 }, // 得分
      { wch: 10 }, // 总分
      { wch: 10 }, // 状态
      { wch: 10 }, // 是否超时
    ];
    worksheet['!cols'] = columnWidths;

    // 添加工作表到工作簿
    XLSX.utils.book_append_sheet(workbook, worksheet, '考试记录');

    // 生成Excel文件的Buffer
    const excelBuffer = XLSX.write(workbook, { type: 'buffer', bookType: 'xlsx' });

    // 设置响应头
    const filename = `考试记录_${new Date().toISOString().slice(0, 10)}.xlsx`;
    res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
    res.setHeader('Content-Disposition', `attachment; filename="${encodeURIComponent(filename)}"`);
    res.setHeader('Content-Length', excelBuffer.length);

    // 发送文件
    res.send(excelBuffer);

  } catch (error) {
    console.error("导出考试记录失败:", error);
    res.status(EnumStatusCode.INTERNAL_SERVER_ERROR).json({
      code: EnumStatusCode.INTERNAL_SERVER_ERROR,
      message: "导出失败",
      data: null,
    });
  }
});

// 获取单个考试记录详情
examRecordRouter.get("/:id", async (req: Request, res: Response) => {
  try {
    const { id } = req.params;
    const record = await ExamRecord.findById(id)
      .populate("user_id", "username phone")
      .populate("exam_id", "_id exam_name")
      .populate("answers.question_id", "content type options answer score");

    if (!record) {
      return res.status(EnumStatusCode.NOT_FOUND).json({
        code: EnumStatusCode.NOT_FOUND,
        message: "考试记录不存在",
        data: null,
      });
    }

    // 如果是已完成的记录，计算排名
    let rank = null;
    if (record.status === 'completed' && record.score !== undefined) {
      const rankingCount = await ExamRecord.countDocuments({
        exam_id: record.exam_id,
        status: 'completed',
        $or: [
          { score: { $gt: record.score } },
          { 
            score: record.score, 
            submit_time: { $lt: record.submit_time }
          }
        ]
      });
      rank = rankingCount + 1;
    }

    // 添加排名信息到结果中
    const result = {
      ...record.toObject(),
      rank
    };

    res.json({
      code: EnumStatusCode.SUCCESS,
      message: "success",
      data: result,
    });
  } catch (error) {
    console.error("获取考试记录详情失败:", error);
    res.status(EnumStatusCode.INTERNAL_SERVER_ERROR).json({
      code: EnumStatusCode.INTERNAL_SERVER_ERROR,
      message: "服务器内部错误",
      data: null,
    });
  }
});

// 创建考试记录（学生开始考试）
examRecordRouter.post("/start", async (req: Request, res: Response) => {
  try {
    const { exam_id } = req.body;
    if (!req.user) {
      return res.status(EnumStatusCode.BAD_REQUEST).json({
        code: EnumStatusCode.BAD_REQUEST,
        message: "用户不存在",
        data: null,
      });
    }
    const { user_id } = req.user;
    // 验证必填字段
    if (!exam_id) {
      return res.status(EnumStatusCode.BAD_REQUEST).json({
        code: EnumStatusCode.BAD_REQUEST,
        message: "活动ID为必填项",
        data: null,
      });
    }

    // 检查考试活动是否存在且启用
    const activity = await Exam.findById(exam_id);
    if (!activity || !activity.is_enabled) {
      return res.status(EnumStatusCode.NOT_FOUND).json({
        code: EnumStatusCode.NOT_FOUND,
        message: "考试活动不存在或未启用",
        data: null,
      });
    }

    // 检查是否在考试时间内
    const now = new Date();
    if (now < activity.start_time || now > activity.end_time) {
      return res.status(EnumStatusCode.BAD_REQUEST).json({
        code: EnumStatusCode.BAD_REQUEST,
        message: "不在考试时间范围内",
        data: null,
      });
    }

    // 检查是否已经参加过考试
    const existingRecord = await ExamRecord.findOne({
      user_id,
      exam_id,
      status: { $in: ["completed", "timeout"] },
    });

    if (existingRecord) {
      return res.status(EnumStatusCode.BAD_REQUEST).json({
        code: EnumStatusCode.BAD_REQUEST,
        message: "您已经参加过此次考试，不能重复参加",
        data: null,
      });
    }

    // 检查是否已经有正在进行的考试记录
    const ongoingRecord = await ExamRecord.findOne({
      user_id,
      exam_id,
      status: "in_progress",
    });

    if (ongoingRecord) {
      // 如果已经有正在进行的记录，返回该记录信息而不是创建新的
      const existingOngoingRecord = await ExamRecord.findById(ongoingRecord._id)
        .populate("user_id", "username phone")
        .populate({
          path: "exam_id",
          populate: {
            path: "paper",
            populate: {
              path: "question_list",
            },
          },
        });

      return res.json({
        code: EnumStatusCode.SUCCESS,
        message: "继续您的考试",
        data: {
          record_id: existingOngoingRecord!._id,
          activity: existingOngoingRecord!.exam_id,
        },
      });
    }

    const newRecord = new ExamRecord({
      user_id,
      exam_id,
      start_time: new Date(),
      answers: [],
      status: "in_progress",
    });

    await newRecord.save();

    const savedRecord = await ExamRecord.findById(newRecord._id)
      .populate("user_id", "username phone")
      .populate({
        path: "exam_id",
        populate: {
          path: "paper",
          populate: {
            path: "question_list",
          },
        },
      });

    if (!savedRecord) {
      return res.status(EnumStatusCode.INTERNAL_SERVER_ERROR).json({
        code: EnumStatusCode.INTERNAL_SERVER_ERROR,
        message: "创建考试记录失败",
        data: null,
      });
    }

    res.status(EnumStatusCode.CREATED).json({
      code: EnumStatusCode.CREATED,
      message: "考试开始成功",
      data: {
        record_id: savedRecord._id,
        activity: savedRecord.exam_id,
      },
    });
  } catch (error) {
    console.error("开始考试失败:", error);
    res.status(EnumStatusCode.INTERNAL_SERVER_ERROR).json({
      code: EnumStatusCode.INTERNAL_SERVER_ERROR,
      message: "服务器内部错误",
      data: null,
    });
  }
});

// 提交考试答案
examRecordRouter.put("/:id/submit", async (req: Request, res: Response) => {
  try {
    const { id } = req.params;
    const { answers, is_timeout } = req.body;

    const record = await ExamRecord.findById(id).populate({
      path: "exam_id",
      populate: {
        path: "paper",
        populate: {
          path: "question_list",
        },
      },
    });

    if (!record) {
      return res.status(EnumStatusCode.NOT_FOUND).json({
        code: EnumStatusCode.NOT_FOUND,
        message: "考试记录不存在",
        data: null,
      });
    }

    if (record.status !== "in_progress") {
      return res.status(EnumStatusCode.BAD_REQUEST).json({
        code: EnumStatusCode.BAD_REQUEST,
        message: "考试已结束，无法提交",
        data: null,
      });
    }

    const now = new Date();
    const activity = record.exam_id as any;
    const paper = activity.paper;
    const questions = paper.question_list;

    // 创建答题快照，保存题目当时的状态和用户答案
    const answersSnapshot = [];
    let totalScore = 0;
    let userScore = 0;

    for (const answer of answers) {
      const question = questions.find(
        (q: any) => q._id.toString() === answer.question_id
      );
      if (!question) continue;

      const userAnswers = answer.selected_answers || [];
      const correctAnswers = question.answer || [];
      const questionScore = question.score || 0;

      // 判断答案是否正确
      const isCorrect = arraysEqual(userAnswers.sort(), correctAnswers.sort());
      const earnedScore = isCorrect ? questionScore : 0;

      totalScore += questionScore;
      userScore += earnedScore;

      // 保存完整的答题快照
      answersSnapshot.push({
        question_id: question._id,
        question_snapshot: {
          content: question.content,
          type: question.type,
          options: question.options,
          correct_answer: question.answer,
          score: question.score,
          difficulty: question.difficulty,
        },
        selected_answers: userAnswers,
        is_correct: isCorrect,
        earned_score: earnedScore,
      });
    }

    const updatedRecord = await ExamRecord.findByIdAndUpdate(
      id,
      {
        answers: answersSnapshot,
        submit_time: now,
        status: is_timeout ? "timeout" : "completed",
        is_timeout: is_timeout || false,
        total_score: totalScore,
        user_score: userScore,
        correct_count: answersSnapshot.filter((a) => a.is_correct).length,
        wrong_count: answersSnapshot.filter(
          (a) => !a.is_correct && a.selected_answers.length > 0
        ).length,
        unanswered_count: answersSnapshot.filter(
          (a) => a.selected_answers.length === 0
        ).length,
      },
      { new: true, runValidators: true }
    )
      .populate("user_id", "username phone")
      .populate("exam_id", "exam_name");

    res.json({
      code: EnumStatusCode.SUCCESS,
      message: "考试提交成功",
      data: updatedRecord,
    });
  } catch (error) {
    console.error("提交考试失败:", error);
    res.status(EnumStatusCode.INTERNAL_SERVER_ERROR).json({
      code: EnumStatusCode.INTERNAL_SERVER_ERROR,
      message: "服务器内部错误",
      data: null,
    });
  }
});

// 判断两个数组是否相等
function arraysEqual(a: number[], b: number[]) {
  if (a.length !== b.length) return false;
  return a.every((val, index) => val === b[index]);
}

// 删除考试记录
examRecordRouter.delete("/:id", async (req: Request, res: Response) => {
  try {
    const { id } = req.params;

    const deletedRecord = await ExamRecord.findByIdAndDelete(id);

    if (!deletedRecord) {
      return res.status(EnumStatusCode.NOT_FOUND).json({
        code: EnumStatusCode.NOT_FOUND,
        message: "考试记录不存在",
        data: null,
      });
    }

    res.json({
      code: EnumStatusCode.SUCCESS,
      message: "考试记录删除成功",
      data: null,
    });
  } catch (error) {
    console.error("删除考试记录失败:", error);
    res.status(EnumStatusCode.INTERNAL_SERVER_ERROR).json({
      code: EnumStatusCode.INTERNAL_SERVER_ERROR,
      message: "服务器内部错误",
      data: null,
    });
  }
});

// 获取考试统计数据
examRecordRouter.get("/stats/overview", async (req: Request, res: Response) => {
  try {
    const totalRecords = await ExamRecord.countDocuments();
    const completedRecords = await ExamRecord.countDocuments({
      status: "completed",
    });
    const timeoutRecords = await ExamRecord.countDocuments({
      status: "timeout",
    });
    const inProgressRecords = await ExamRecord.countDocuments({
      status: "in_progress",
    });

    res.json({
      code: EnumStatusCode.SUCCESS,
      message: "success",
      data: {
        total: totalRecords,
        completed: completedRecords,
        timeout: timeoutRecords,
        in_progress: inProgressRecords,
        completion_rate:
          totalRecords > 0
            ? ((completedRecords / totalRecords) * 100).toFixed(2)
            : 0,
      },
    });
  } catch (error) {
    console.error("获取考试统计数据失败:", error);
    res.status(EnumStatusCode.INTERNAL_SERVER_ERROR).json({
      code: EnumStatusCode.INTERNAL_SERVER_ERROR,
      message: "服务器内部错误",
      data: null,
    });
  }
});

// 删除单个考试记录
examRecordRouter.delete("/:id", async (req: Request, res: Response) => {
  try {
    const { id } = req.params;
    const user = req.user;

    // 检查权限：只有管理员可以删除考试记录
    if (user?.role !== "admin") {
      return res.status(EnumStatusCode.FORBIDDEN).json({
        code: EnumStatusCode.FORBIDDEN,
        message: "权限不足，只有管理员可以删除考试记录",
        data: null,
      });
    }

    const record = await ExamRecord.findById(id);
    if (!record) {
      return res.status(EnumStatusCode.NOT_FOUND).json({
        code: EnumStatusCode.NOT_FOUND,
        message: "考试记录不存在",
        data: null,
      });
    }

    await ExamRecord.findByIdAndDelete(id);

    res.json({
      code: EnumStatusCode.SUCCESS,
      message: "删除成功",
      data: null,
    });
  } catch (error) {
    console.error("删除考试记录失败:", error);
    res.status(EnumStatusCode.INTERNAL_SERVER_ERROR).json({
      code: EnumStatusCode.INTERNAL_SERVER_ERROR,
      message: "服务器内部错误",
      data: null,
    });
  }
});

// 批量删除考试记录
examRecordRouter.post("/batch-delete", async (req: Request, res: Response) => {
  try {
    const { ids } = req.body;
    const user = req.user;

    // 检查权限：只有管理员可以删除考试记录
    if (user?.role !== "admin") {
      return res.status(EnumStatusCode.FORBIDDEN).json({
        code: EnumStatusCode.FORBIDDEN,
        message: "权限不足，只有管理员可以删除考试记录",
        data: null,
      });
    }

    if (!ids || !Array.isArray(ids) || ids.length === 0) {
      return res.status(EnumStatusCode.BAD_REQUEST).json({
        code: EnumStatusCode.BAD_REQUEST,
        message: "请提供要删除的记录ID列表",
        data: null,
      });
    }

    const result = await ExamRecord.deleteMany({ _id: { $in: ids } });

    res.json({
      code: EnumStatusCode.SUCCESS,
      message: `成功删除 ${result.deletedCount} 条记录`,
      data: {
        deletedCount: result.deletedCount,
      },
    });
  } catch (error) {
    console.error("批量删除考试记录失败:", error);
    res.status(EnumStatusCode.INTERNAL_SERVER_ERROR).json({
      code: EnumStatusCode.INTERNAL_SERVER_ERROR,
      message: "服务器内部错误",
      data: null,
    });
  }
});

export default examRecordRouter;
